/**
 * Copyright (C) 2013 SHANGHAI VOLKSWAGEN, All rights reserved.
 * License version 1.0, a copy of which has been included with this.
 *
 * @File name：com.market.order.server.service.impl.UserWrapBatchService
 * @Create on：2024/3/13
 * @Author：liuchang
 */
package com.market.order.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.market.order.common.domain.TOrder;
import com.market.order.server.service.ITOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.*;

/**
 * <p>ClassName：UserWrapBatchService</p >
 * <p>Description：</p >
 * <p>Author：liuchang</p >
 * <p>Date：2024/3/13</p >
 */
@Service
public class UserWrapBatchService {

    @Autowired
    private ITOrderService tOrderService;

    private static  int MAX_TASK_NUM=100;//最大任务数

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    //用户储存对象
    private final Queue<Request> queue=new LinkedBlockingQueue<>();

    @PostConstruct
     public void init(){
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(()->{
            int size = queue.size();
            if (size==0){
                return;
            }
            ArrayList<Request> list = new ArrayList<>();
            System.out.println("合并了"+size+"个请求");

            for (int i = 0; i < size; i++) {
                 if (i<=MAX_TASK_NUM){
                     list.add(queue.poll());
                 }
            }

            ArrayList<Request> userReqs = new ArrayList<>();

            Map<String,List<TOrder>> response=tOrderService.queryUserByIdBatch(userReqs);


            for (Request request : list) {
                List<TOrder> result = response.get(request.requestId);
                String jsonString = JSON.toJSONString(request);

                redisTemplate.opsForValue().set(request.getRequestId().toString()+"order",jsonString);

                request.completableFuture.complete(result);
            }


        },100,10, TimeUnit.MILLISECONDS);


    }

    public  class Request{
        String requestId;
        Long userId;

        CompletableFuture<List<TOrder>> completableFuture;

        public Request() {
        }

        public String getRequestId() {
            return requestId;
        }

        public void setRequestId(String requestId) {
            this.requestId = requestId;
        }

        public Long getUserId() {
            return userId;
        }

        public void setUserId(Long userId) {
            this.userId = userId;
        }

        public CompletableFuture<List<TOrder>> getCompletableFuture() {
            return completableFuture;
        }

        public void setCompletableFuture(CompletableFuture<List<TOrder>> completableFuture) {
            this.completableFuture = completableFuture;
        }

        public Request(String requestId, Long userId, CompletableFuture<List<TOrder>> completableFuture) {
            this.requestId = requestId;
            this.userId = userId;
            this.completableFuture = completableFuture;
        }

        @Override
        public String toString() {
            return "Request{" +
                    "requestId='" + requestId + '\'' +
                    ", userId=" + userId +
                    ", completableFuture=" + completableFuture +
                    '}';
        }
    }
    public List<TOrder> queryUser(Long userId) {
        Request request = new Request();
        request.requestId= UUID.randomUUID().toString().replaceAll("-","");
        request.userId=userId;

        CompletableFuture<List<TOrder>> future = new CompletableFuture<>();
        request.completableFuture=future;
          //将对象传入队列
          queue.offer(request);

        try {
            return future.get();
        } catch (InterruptedException e) {

        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }

        return null;


    }
}
